package com.mini.service;

import com.mini.conditon.BelongingInfoCondition;
import com.mini.config.BusinessException;
import com.mini.constant.GoalStatusEnum;
import com.mini.model.BusinessBelongingInfo;
import com.mini.repository.BusinessBelongingInfoRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author: zhaocg
 * @created: 2020/12/02 11:57
 */
@Slf4j
@Service
public class BusinessBelongingInfoService extends BaseService {

    @Autowired
    private BusinessBelongingInfoRepository belongingInfoRepository;

    @Autowired
    private MiniAdminService miniAdminService;


    /**
     * 根据条件查询所属组
     *
     * @param condition
     * @return
     */
    public List<BusinessBelongingInfo> belongingInfoList(BelongingInfoCondition condition){
        List<BusinessBelongingInfo> belongingInfoList = belongingInfoRepository.findAll(getRelationAppletInfoSpecification(condition));
        if (!CollectionUtils.isEmpty(belongingInfoList)) {
            belongingInfoList.stream().forEach(belongingInfo->{
                String deptOrgName = miniAdminService.getOrgGroupName(belongingInfo.getDeptId());
                belongingInfo.setShowOrgName(deptOrgName);
            });
        }
        return belongingInfoList;
    }

    private Specification<BusinessBelongingInfo> getRelationAppletInfoSpecification(BelongingInfoCondition condition){
        return new Specification<BusinessBelongingInfo>() {
            @Override
            public Predicate toPredicate(Root<BusinessBelongingInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (condition.getBusinessGroupId() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("businessGroupId").as(Long.class), condition.getBusinessGroupId()));
                }
                if (!CollectionUtils.isEmpty(condition.getDeptIdList())) {
                    if (condition.getDeptIdList().size() == 1) {
                        predicates.add(criteriaBuilder.equal(root.get("deptId").as(Long.class) , condition.getDeptIdList().get(0)));
                    } else {
                        CriteriaBuilder.In<Long> in = criteriaBuilder.in(root.get("deptId"));
                        condition.getDeptIdList().forEach(o -> in.value(o));
                        predicates.add(in);
                    }
                }
                criteriaQuery.orderBy(criteriaBuilder.desc(root.get("createTime")));
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }

    /**
     * 根据业务组ID获取所有所属组
     *
     * @param businessGroupId
     * @return
     */
    public List<BusinessBelongingInfo> findByGroupId(Long businessGroupId){
        List<BusinessBelongingInfo> belongingInfoList =
                belongingInfoRepository.findByBusinessGroupIdOrderByCreateTimeDesc(businessGroupId);
        if (!CollectionUtils.isEmpty(belongingInfoList)) {
            belongingInfoList.stream().forEach(belongingInfo -> {
                String deptOrgName = miniAdminService.getOrgGroupName(belongingInfo.getDeptId());
                belongingInfo.setShowOrgName(deptOrgName);
            });
        }
        return belongingInfoList;
    }

    /**
     * 根据业务组ID获取所属组- 获取前两条数据
     *
     * @param businessGroupId
     * @return
     */
    public List<BusinessBelongingInfo> findTop2ByBusinessGroupId(Long businessGroupId){
        List<BusinessBelongingInfo> belongingInfoList =
                belongingInfoRepository.findTop2ByBusinessGroupIdOrderByCreateTimeDesc(businessGroupId);
        if (!CollectionUtils.isEmpty(belongingInfoList)) {
            belongingInfoList.stream().forEach(belongingInfo -> {
                String deptOrgName = miniAdminService.getOrgGroupName(belongingInfo.getDeptId());
                belongingInfo.setShowOrgName(deptOrgName);
            });
        }
        return belongingInfoList;
    }

    /**
     * 根据业务组ID获取业务范围数据总数
     *
     * @param businessGroupId
     * @return
     */
    public Long countByBusinessGroupId(Long businessGroupId){
        return belongingInfoRepository.countByBusinessGroupId(businessGroupId);
    }

    /**
     * 保存所属组
     *
     * @param belongingInfo
     * @return
     */
    public BusinessBelongingInfo save(BusinessBelongingInfo belongingInfo){
        Date date = new Date();
        belongingInfo.setCreateTime(date);
        belongingInfo.setUpdateTime(date);
        belongingInfo.setStates(GoalStatusEnum.VALID.getCode());
        return belongingInfoRepository.save(belongingInfo);
    }

    /**
     * 删除所属组
     *
     * @param id
     */
    public void deleted(Long id){
        BusinessBelongingInfo belongingInfo = findById(id);
        if (Objects.isNull(belongingInfo)) {
            throw new BusinessException("数据不合法");
        }
        belongingInfoRepository.delete(belongingInfo);
    }

    /**
     * 根据ID查找实体
     *
     * @param id
     * @return
     */
    public BusinessBelongingInfo findById(Long id){
        return belongingInfoRepository.findOne(id);
    }

    /**
     * 根据业务组ID修改所属组状态
     *
     * @param businessGroupId
     */
    public void deletedByGroupId(Long businessGroupId){
        belongingInfoRepository.deletedByGroupId(businessGroupId);
    }

    /**
     * 根据业务组ID列表，获取所有所属组数据
     *
     * @param businessGroupIds
     * @return
     */
    public List<BusinessBelongingInfo> findByBusinessGroupIdIn(List<Long> businessGroupIds){
        return belongingInfoRepository.findByBusinessGroupIdIn(businessGroupIds);
    }

    /**
     * 根据军团ID，获取所有所属组数据
     *
     * @param legionId
     * @return
     */
    public List<BusinessBelongingInfo> findByLegionId(Long legionId){
        return belongingInfoRepository.findByLegionId(legionId);
    }
}
